# -*- python -*-
# ex: set syntax=python:

import os

xapian_git_root = 'https://git.xapian.org/xapian'
tarball_root = "https://oligarchy.co.uk/xapian/master/"
tarball_root_stable = "https://oligarchy.co.uk/xapian/RELEASE/1.4/"

# This is the dictionary that the buildmaster pays attention to. We also use
# a shorter alias to save typing.
c = BuildmasterConfig = {}

####### BUILDSLAVES

# The 'slaves' list defines the set of recognized buildslaves. Each element is
# a BuildSlave object, specifying a unique slave name and password.  The same
# slave name and password must be configured on the slave.
from buildbot.buildslave import BuildSlave

class MySlave(BuildSlave):
    def __init__(self, name, **kwargs):
        password = self.get_pass(name)
        BuildSlave.__init__(self, name, password, **kwargs)

    def get_pass(self, name):
        # get the password based on the name
        path = os.path.join(os.path.dirname(__file__), "%s.pass" % name)
        pw = open(path).read().strip()
        return pw

c['slaves'] = [MySlave(h, max_builds=1) for h in (
        # Off-line since July 2014: "linux_i686_earlgrey",
        # Off-line until Summer 2018: "macos_broteas",
        # Off-line since October 2014: "gentoo_jbergstroem",
        "linux_ojwb",
        "debian_hppa_gcc61",
        "fedora_ppc64_gcc110",
        "aix_gcc111",
        "unstable11s.opencsw",
    )]

# 'slavePortnum' defines the TCP port to listen on for connections from slaves.
# This must match the value configured into the buildslaves (with their
# --master option)
c['slavePortnum'] = 9989

####### CHANGESOURCES

# the 'change_source' setting tells the buildmaster how it should find out
# about source code changes.

c['change_source'] = []

from buildbot.changes.gitpoller import GitPoller
c['change_source'].append(GitPoller(
    repourl=xapian_git_root,
    workdir='/home/xapian-buildbot/master/gitpoller-work',
    pollinterval=60
))

from tarsource import TarPoller
c['change_source'].append(TarPoller(tarball_root, branch='tar', archives=('xapian-core', 'xapian-omega', 'xapian-bindings'), pollinterval=60))
c['change_source'].append(TarPoller(tarball_root_stable, branch='tar', archives=('xapian-core', 'xapian-omega', 'xapian-bindings'), pollinterval=60))

####### SCHEDULERS

# Configure the Schedulers, which decide how to react to incoming changes.

from buildbot.schedulers.basic import SingleBranchScheduler
c['schedulers'] = []

c['schedulers'].append(SingleBranchScheduler(
    name="xapian_git_quick",
    branch='master',
    builderNames=['git update linux amd64'],
    treeStableTimer=70))

c['schedulers'].append(SingleBranchScheduler(
    name="xapian_tar",
    branch="tar",
    builderNames=[
#        'xapian tar macos',
#        "xapian tar gentoo",
        "xapian tar linux ojwb",
        "xapian tar mingw-cross",
        "xapian tar mingw64-cross",
        "xapian tar android",
    ],
    treeStableTimer=0))
c['schedulers'].append(SingleBranchScheduler(
    name="xapian_tar_weekly",
    branch="tar",
    builderNames=[
        "xapian tar fedora ppc64",
        "xapian tar debian hppa",
        "xapian tar aix",
        "xapian tar aix xlc",
#        "xapian tar gentoo nochert",
#        "xapian tar gentoo noglass",
        'tar solaris11s',
        'tar solaris11s suncc',
        'stable tar solaris11s',
        'stable tar solaris11s suncc'
    ],
    treeStableTimer=7*24*60*60))

#c['schedulers'].append(SingleBranchScheduler(
#    name="xapian_git_slow",
#    branch='master',
#    treeStableTimer=15*60))
c['schedulers'].append(SingleBranchScheduler(
    name="xapian_git_1hr",
    branch='master',
    builderNames=[
        'git update log assert linux amd64',
#        'git update log assert macos',
#        'git update macos',
        'git update clang linux amd64'
    ],
    treeStableTimer=60*60))
c['schedulers'].append(SingleBranchScheduler(
    name="xapian_git_2hr",
    branch='master',
    builderNames=['git update glibcxxdebug linux amd64'],
    treeStableTimer=60*60))
c['schedulers'].append(SingleBranchScheduler(
    name="xapian_git_3hr",
    branch='master',
    builderNames=[
#        'git update linux i686'
    ],
    treeStableTimer=3*60*60))
c['schedulers'].append(SingleBranchScheduler(
    name="xapian_git_4h",
    branch='master',
    builderNames=['git update assert linux amd64'],
    treeStableTimer=4*60*60))
c['schedulers'].append(SingleBranchScheduler(
    name="xapian_git_5h",
    branch='master',
    builderNames=[
        'git update log linux amd64',
        'git update -Os linux amd64',
        'stable tar assert linux amd64',
        'stable tar log linux amd64',
        'stable tar glibcxxdebug linux amd64',
        'stable tar log assert linux amd64',
#        'stable tar macos',
#        'stable tar gentoo',
#        'stable tar gentoo nobrass',
#        'stable tar gentoo nochert',
#        'stable tar gentoo noflint',
        'stable tar linux ojwb',
        'stable tar clang linux amd64',
        'stable tar fedora ppc64',
        'stable tar debian hppa',
        'stable tar aix',
        'stable tar aix xlc',
        'stable tar mingw-cross',
        'stable tar mingw64-cross',
    ],
    treeStableTimer=5*60*60))
#c['schedulers'].append(SingleBranchScheduler(
#    name="xapian_git_veryslow4",
#    branch='master',
#    treeStableTimer=6*60*60))
c['schedulers'].append(SingleBranchScheduler(
    name="xapian_git_veryslow5",
    branch='master',
    builderNames=[
        'git update valgrind linux amd64',
#        'git update asan linux amd64',
#        'git update ubsan linux amd64',
        'git update lcov linux amd64'
    ],
    treeStableTimer=7*60*60))

####### BUILDERS

# The 'builders' list defines the Builders, which tell Buildbot how to perform a build:
# what steps, and which slaves can execute them.  Note that any particular build will
# only take place on one slave.

from buildbot.config import BuilderConfig
from xapian_factories import *

c['builders'] = []

for builder in [
    {
    'name': 'git update linux amd64',
    'slavename': 'linux_ojwb',
    'factory': git_updated_factory2(xapian_git_root, ["--without-java"]),
    },
    {
    'name': 'git update assert linux amd64',
    'slavename': 'linux_ojwb',
    'factory': git_debug_updated_factory(xapian_git_root, ["--enable-assertions=yes", "--without-java"]),
    },
    {
    'name': 'stable tar assert linux amd64',
    'slavename': 'linux_ojwb',
    'factory': tarball_updated_factory(tarball_root_stable, configure_opts=["--enable-assertions=yes", "--without-java"]),
    },
    {
    'name': 'git update log linux amd64',
    'slavename': 'linux_ojwb',
    'factory': git_debug_updated_factory(xapian_git_root, ["--enable-log=yes", "--without-java"]),
    },
    {
    'name': 'stable tar log linux amd64',
    'slavename': 'linux_ojwb',
    'factory': tarball_updated_factory(tarball_root_stable, configure_opts=["--enable-log=yes", "--without-java"]),
    },
    {
    'name': 'git update glibcxxdebug linux amd64',
    'slavename': 'linux_ojwb',
    'factory': git_debug_updated_factory(xapian_git_root, ["CPPFLAGS=-D_GLIBCXX_DEBUG", "--without-java"]),
    },
    {
    'name': 'stable tar glibcxxdebug linux amd64',
    'slavename': 'linux_ojwb',
    'factory': tarball_updated_factory(tarball_root_stable, configure_opts=["CPPFLAGS=-D_GLIBCXX_DEBUG", "--without-java"]),
    },
    {
    'name': 'git update log assert linux amd64',
    'slavename': 'linux_ojwb',
    'factory': git_debug_updated_factory(xapian_git_root, ["--enable-assertions=yes", "--enable-log=yes", "--without-java"]),
    },
    {
    'name': 'stable tar log assert linux amd64',
    'slavename': 'linux_ojwb',
    'factory': tarball_updated_factory(tarball_root_stable, configure_opts=["--enable-assertions=yes", "--enable-log=yes", "--without-java"]),
    },

#    {
#    'name': 'git update linux i686',
#    'slavename': 'linux_i686_earlgrey',
#    'factory': git_updated_factory(xapian_git_root),
#    },

#    {
#    'name': 'git update macos',
#    'slavename': 'macos_broteas',
#    'factory': git_updated_factory(xapian_git_root),
#    },
#    {
#    'name': 'git update log assert macos',
#    'slavename': 'macos_broteas',
#    'factory': git_debug_updated_factory(xapian_git_root, ["--enable-assertions=yes", "--enable-log=yes"]),
#    },
    {
    'name': "git update valgrind linux amd64",
    'slavename': 'linux_ojwb',
    'factory': git_updated_valgrind_factory(xapian_git_root, ["--without-java"]),
    },
# Runs out of memory during "make check"
#    {
#    'name': "git update asan linux amd64",
#    'slavename': 'linux_ojwb',
#    'factory': git_updated_factory(xapian_git_root, usedocs=False, configure_opts=["CXXFLAGS=-fsanitize=address -O2 -g -fno-omit-frame-pointer", "CFLAGS=-fsanitize=address -O2 -g -fno-omit-frame-pointer"]),
#    },
# Runs out of memory
#    {
#    'name': "git update ubsan linux amd64",
#    'slavename': 'linux_ojwb',
#    'factory': git_updated_factory(xapian_git_root, usedocs=False, configure_opts=["CXXFLAGS=-fsanitize=undefined,shift,integer-divide-by-zero,unreachable,null,return,signed-integer-overflow -O2 -g -fno-omit-frame-pointer", "CFLAGS=-fsanitize=undefined,shift,integer-divide-by-zero,unreachable,vla-bound,null,signed-integer-overflow"]),
#    # float-divide-by-zero,float-cast-overflow - need newer GCC
#    },
    {
    'name': "git update lcov linux amd64",
    'slavename': 'linux_ojwb',
    'factory': git_updated_lcov_factory(xapian_git_root),
    },
#    {
#    'name': "xapian tar macos",
#    'slavename': 'macos_broteas',
#    'factory': tarball_updated_factory(tarball_root),
#    },
#    {
#    'name': 'stable tar macos',
#    'slavename': 'macos_broteas',
#    'factory': tarball_updated_factory(tarball_root_stable),
#    },
#    {
#    'name': "xapian tar gentoo",
#    'slavename': 'gentoo_jbergstroem',
#    'factory': tarball_updated_factory(tarball_root, configure_opts=["--without-java", "PYTHON=/usr/bin/python2"]),
#    },
#    {
#    'name': 'stable tar gentoo',
#    'slavename': 'gentoo_jbergstroem',
#    'factory': tarball_updated_factory(tarball_root_stable, configure_opts=["--without-java"]),
#    },
#    {
#    'name': "xapian tar gentoo noglass",
#    'slavename': 'gentoo_jbergstroem',
#    'factory': tarball_updated_factory(tarball_root, configure_opts=["--without-java", "--disable-backend-glass"]),
#    },
#    {
#    'name': 'stable tar gentoo nobrass',
#    'slavename': 'gentoo_jbergstroem',
#    'factory': tarball_updated_factory(tarball_root_stable, configure_opts=["--without-java", "--disable-backend-brass"]),
#    },
#    {
#    'name': "xapian tar gentoo nochert",
#    'slavename': 'gentoo_jbergstroem',
#    'factory': tarball_updated_factory(tarball_root, configure_opts=["--without-java", "--disable-backend-chert"]),
#    },
#    {
#    'name': 'stable tar gentoo nochert',
#    'slavename': 'gentoo_jbergstroem',
#    'factory': tarball_updated_factory(tarball_root_stable, configure_opts=["--without-java", "--disable-backend-chert"]),
#    },
#    {
#    'name': 'stable tar gentoo noflint',
#    'slavename': 'gentoo_jbergstroem',
#    'factory': tarball_updated_factory(tarball_root_stable, configure_opts=["--without-java", "--disable-backend-flint"]),
#    },
    {
    'name': "xapian tar linux ojwb",
    'slavename': 'linux_ojwb',
    'factory': tarball_updated_factory(tarball_root),
    },
    {
    'name': 'stable tar linux ojwb',
    'slavename': 'linux_ojwb',
    'factory': tarball_updated_factory(tarball_root_stable),
    },
    {
    'name': 'git update -Os linux amd64',
    'slavename': 'linux_ojwb',
    'factory': git_debug_updated_factory(xapian_git_root, ["CFLAGS=-Os", "CXXFLAGS=-Os"]),
    },
    {
    'name': 'git update clang linux amd64',
    'slavename': 'linux_ojwb',
    'factory': git_debug_updated_factory(xapian_git_root, ["CC=clang-3.5", "CXX=clang++-3.5"]),
    },
    {
    'name': 'stable tar clang linux amd64',
    'slavename': 'linux_ojwb',
    'factory': tarball_updated_factory(tarball_root_stable, configure_opts=["CC=clang-3.5", "CXX=clang++-3.5"]),
    },
    {
    'name': "xapian tar fedora ppc64",
    'slavename': 'fedora_ppc64_gcc110',
    'factory': tarball_updated_factory(tarball_root),
    },
    {
    'name': 'stable tar fedora ppc64',
    'slavename': 'fedora_ppc64_gcc110',
    'factory': tarball_updated_factory(tarball_root_stable),
    },
    {
    'name': "xapian tar debian hppa",
    'slavename': 'debian_hppa_gcc61',
    'factory': tarball_updated_factory(tarball_root),
    },
    {
    'name': "stable tar debian hppa",
    'slavename': 'debian_hppa_gcc61',
    'factory': tarball_updated_factory(tarball_root_stable),
    },
    # Perl bindings fail to build on AIX due to compiler error - not sure
    # what's going on there.
    # /usr/opt/perl5/lib/5.10.1/aix-thread-multi/CORE/reentr.h:780:21: error: field '_srandom_struct' has incomplete type
    #  struct random_data _srandom_struct;
    {
    'name': "xapian tar aix",
    'slavename': 'aix_gcc111',
    'factory': tarball_updated_factory(tarball_root, omega=False, configure_opts=['--without-perl']),
    },
    {
    'name': "stable tar aix",
    'slavename': 'aix_gcc111',
    'factory': tarball_updated_factory(tarball_root_stable, omega=False, configure_opts=['--without-perl']),
    },
    {
    'name': "xapian tar aix xlc",
    'slavename': 'aix_gcc111',
    'factory': tarball_updated_factory(tarball_root, omega=False, configure_opts=['CXX=/usr/bin/xlC', 'CC=/usr/bin/xlc', '--without-perl']),
    },
    {
    'name': "stable tar aix xlc",
    'slavename': 'aix_gcc111',
    'factory': tarball_updated_factory(tarball_root_stable, omega=False, configure_opts=['CXX=/usr/bin/xlC', 'CC=/usr/bin/xlc', '--without-perl']),
    },
    {
    'name': "xapian tar mingw-cross",
    'slavename': 'linux_ojwb',
    # MXE doesn't build shared libraries; bindings don't cross-compile well.
    'factory': tarball_updated_factory(tarball_root, nocheck=True, bindings=False, configure_opts=["--disable-shared", "--host=i686-pc-mingw32", "CC=/opt/mxe/usr/bin/i686-pc-mingw32-gcc", "CXX=/opt/mxe/usr/bin/i686-pc-mingw32-g++"]),
    'env':{'PATH': '/opt/mxe/usr/bin:/usr/lib/ccache:/usr/bin:/bin'},
    },
    {
    'name': "xapian tar mingw64-cross",
    'slavename': 'linux_ojwb',
    # MXE doesn't build shared libraries; bindings don't cross-compile well.
    'factory': tarball_updated_factory(tarball_root, nocheck=True, bindings=False, configure_opts=["--disable-shared", "--host=x86_64-w64-mingw32", "CC=/opt/mxe/usr/bin/x86_64-w64-mingw32-gcc", "CXX=/opt/mxe/usr/bin/x86_64-w64-mingw32-g++"]),
    'env':{'PATH': '/opt/mxe/usr/bin:/usr/lib/ccache:/usr/bin:/bin'},
    },
    {
    'name': "stable tar mingw-cross",
    'slavename': 'linux_ojwb',
    # MXE doesn't build shared libraries; bindings don't cross-compile well.
    'factory': tarball_updated_factory(tarball_root_stable, nocheck=True, bindings=False, configure_opts=["--disable-shared", "--host=i686-pc-mingw32", "CC=/opt/mxe/usr/bin/i686-pc-mingw32-gcc", "CXX=/opt/mxe/usr/bin/i686-pc-mingw32-g++"]),
    'env':{'PATH': '/opt/mxe/usr/bin:/usr/lib/ccache:/usr/bin:/bin'},
    },
    {
    'name': "stable tar mingw64-cross",
    'slavename': 'linux_ojwb',
    # MXE doesn't build shared libraries; bindings don't cross-compile well.
    'factory': tarball_updated_factory(tarball_root_stable, nocheck=True, bindings=False, configure_opts=["--disable-shared", "--host=x86_64-w64-mingw32", "CC=/opt/mxe/usr/bin/x86_64-w64-mingw32-gcc", "CXX=/opt/mxe/usr/bin/x86_64-w64-mingw32-g++", "CPPFLAGS=-DMINGW_HAS_SECURE_API"]),
    'env':{'PATH': '/opt/mxe/usr/bin:/usr/lib/ccache:/usr/bin:/bin'},
    },
    {
    'name': 'tar solaris11s',
    'slavename': 'unstable11s.opencsw',
    'factory': tarball_updated_factory(tarball_root, omega=False),
    },
    {
    'name': 'tar solaris11s suncc',
    'slavename': 'unstable11s.opencsw',
    'factory': tarball_updated_factory(tarball_root, omega=False, configure_opts=["CC=/opt/solarisstudio12.4/bin/cc", "CXX=/opt/solarisstudio12.4/bin/CC"]),
    },
    {
    'name': 'stable tar solaris11s',
    'slavename': 'unstable11s.opencsw',
    'factory': tarball_updated_factory(tarball_root_stable, omega=False),
    },
    {
    'name': 'stable tar solaris11s suncc',
    'slavename': 'unstable11s.opencsw',
    'factory': tarball_updated_factory(tarball_root_stable, omega=False, configure_opts=["CC=/opt/solarisstudio12.4/bin/cc", "CXX=/opt/solarisstudio12.4/bin/CC"]),
    },
    {
    'name': 'xapian tar android',
    'slavename': 'linux_ojwb',
    'factory': tarball_updated_factory(tarball_root, configure_opts=["--host=arm-linux-androideabi", "--prefix=/home/bill/android/xapian-install", "LDFLAGS=-fPIE -pie", "--disable-shared", "--with-pic"], nocheck=True, omega=False, bindings=False),
    'env':{'PATH': '/usr/bin:/bin:/home/bill/android/toolchain/bin'},
    },
]:
    name = builder['name']
    if name.find('stable') != -1:
        builder['category'] = 'stable'
    else:
        builder['category'] = 'dev'
    if not 'env' in builder:
        builder['env'] = {'VERBOSE': '1'}
    elif not 'VERBOSE' in builder['env']:
        builder['env']['VERBOSE'] = '1'
    c['builders'].append(BuilderConfig(**builder))

### FIXME: more builders...

####### STATUS TARGETS

# 'status' is a list of Status Targets. The results of each build will be
# pushed to these targets. buildbot/status/*.py has a variety to choose from,
# including web pages, email senders, and IRC bots.

c['status'] = []

from buildbot.status import html
c['status'].append(html.WebStatus(http_port=10300))

# from buildbot.status import mail
# c['status'].append(mail.MailNotifier(fromaddr="buildbot@localhost",
#                                      extraRecipients=["builds@example.com"],
#                                      sendToInterestedUsers=False))
#
#from buildbot.status import words
import words # Use our own fixed version
path = os.path.join(os.path.dirname(__file__), "password.irc")
irc_password = open(path).read().strip()
c['status'].append(words.IRC(host="irc.freenode.net", nick="xapian-buildbot",
                             password=irc_password,
                             allowForce=True,
                             channels=["#xapian-devel"]))

# from buildbot.status import client
# c['status'].append(client.PBListener(9988))


####### DEBUGGING OPTIONS

# if you set 'debugPassword', then you can connect to the buildmaster with
# the diagnostic tool in contrib/debugclient.py . From this tool, you can
# manually force builds and inject changes, which may be useful for testing
# your buildmaster without actually committing changes to your repository (or
# before you have a functioning 'change_source' set up). The debug tool uses the
# same port number as the slaves do: 'slavePortnum'.

#c['debugPassword'] = "debugpassword"

# if you set 'manhole', you can ssh into the buildmaster and get an
# interactive python shell, which may be useful for debugging buildbot
# internals. It is probably only useful for buildbot developers. You can also
# use an authorized_keys file, or plain telnet.
#from buildbot import manhole
#c['manhole'] = manhole.PasswordManhole("tcp:9999:interface=127.0.0.1",
#                                       "admin", "password")


####### PROJECT IDENTITY

# the 'title' string will appear at the top of this buildbot
# installation's html.WebStatus home page (linked to the
# 'titleURL') and is embedded in the title of the waterfall HTML page.

c['title'] = "Xapian"
c['titleURL'] = "https://xapian.org/"

# the 'buildbotURL' string should point to the location where the buildbot's
# internal web server (usually the html.WebStatus page) is visible. This
# typically uses the port number set in the Waterfall 'status' entry, but
# with an externally-visible host name which the buildbot cannot figure out
# without some help.

c['buildbotURL'] = "https://buildbot.xapian.org/"
